#include "fyp/render/ShaderImpl.h"

//------------------------------------------------------------------------------
// additional header includes
#include "fyp/render/ResourceFactory.h"

#include <d3dx9.h>

//------------------------------------------------------------------------------
namespace ming
{
namespace fyp
{
namespace render
{
	//--------------------------------------------------------------------------
	TShaderImpl::TShaderImpl(const char *filename, const char *technique, TResourceFactory *resFactory) :
		mResFactory(resFactory),
		mTechnique(technique)
	{
		mEffect = mResFactory->LoadEffect(filename);
	}
	
	//--------------------------------------------------------------------------
	TShaderImpl::~TShaderImpl()
	{
		if(mEffect)
			mResFactory->UnloadEffect(mEffect);
	}

	//--------------------------------------------------------------------------
	void TShaderImpl::BeginRender()
	{
		if(mEffect)
		{
			mEffect->SetTechnique( mTechnique.c_str() );
			mEffect->Begin(&mPassCnt, 0);

			mCurrPass = 0;
		}
	}

	//--------------------------------------------------------------------------
	bool TShaderImpl::BeginPass()
	{
		if(!mEffect)
			return false;

		if(mCurrPass >= mPassCnt)
			return false;

		mEffect->BeginPass(mCurrPass);

		return true;
	}

	//--------------------------------------------------------------------------
	void TShaderImpl::EndPass()
	{
		if(!mEffect) return;

		mEffect->EndPass();
		++mCurrPass;
	}

	//--------------------------------------------------------------------------
	void TShaderImpl::EndRender()
	{
		if(!mEffect) return;

		mEffect->End();
	}

	//--------------------------------------------------------------------------
	void TShaderImpl::BindParam(
		const char *semantic,
		const void *value,
		size_t size)
	{
		if(!mEffect) return;

		D3DXHANDLE handle = mEffect->GetParameterBySemantic(0, semantic);

		if(handle)
			mEffect->SetValue(handle, value, (UINT)size );
	}

	//--------------------------------------------------------------------------
	bool TShaderImpl::HasParam(const char *semantic)
	{
		if(!mEffect) return false;

		return mEffect->GetParameterBySemantic(0, semantic) != NULL;
	}

	//--------------------------------------------------------------------------
	void TShaderImpl::CommitParams()
	{
		if(!mEffect) return;

		mEffect->CommitChanges();
	}
	
	//--------------------------------------------------------------------------
}
}
}
